package com.qt.myboot.filter;


import com.qt.myboot.common.BootConstants;
import com.qt.myboot.dao.UserRepository;
import com.qt.myboot.entity.User;
import com.qt.myboot.enums.UserErrorCodeEnum;
import com.qt.myboot.exception.UserErrorCodeException;
import com.qt.myboot.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.web.filter.authz.PermissionsAuthorizationFilter;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


/**
 * Despription:
 *
 * @Autor: xusl
 * @Date: 2019/5/31 16:52
 * @Version: 1.0
 **/
@Slf4j
public class ShiroFilter extends PermissionsAuthorizationFilter {


    private UserRepository userRepository;

    public ShiroFilter(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Override
    public boolean isAccessAllowed(ServletRequest req, ServletResponse res, Object mappedValue) throws IOException {
        boolean flag = false ;
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        // 获取 HTTP HEAD 中的 TOKEN
        String authorization = request.getHeader("Authorization");
        if (StringUtils.isEmpty(authorization)) {
            throw new UserErrorCodeException(UserErrorCodeEnum.US47);
        }
        // 校验 TOKEN
        flag = StringUtils.isNotBlank(authorization) ? JwtUtil.checkJWT(authorization) : false;
        // 如果校验未通过，返
        // 回 401 状态
        Jws<Claims> claimsJws = JwtUtil.parseJWT(authorization);
        String userName = claimsJws.getBody().getSubject();
        log.info("userName = {}", userName);
        User userVO = userRepository.findByUserNameEquals(userName);
        log.info("userVO = {}", userVO.toString());
        long expireTime = claimsJws.getBody().getExpiration().getTime();
        log.info("expireTime = {}", expireTime);
        if (DateTime.now().toDate().getTime() > expireTime) {
            // token 过期
            throw new UserErrorCodeException(UserErrorCodeEnum.US35);

        }else {
            // 未过期
            if (expireTime - DateTime.now().toDate().getTime() < 1000 * 60) {
                // token快过期 小于一分钟 生成一个新的token
                String buildToken = JwtUtil.buildJWT(userVO.getUserName(), BootConstants.jwtAud,
                                                    String.valueOf(userVO.getId()), BootConstants.SIGNATURE,
                                                    DateTime.now().toDate(), 3);
                response.setHeader("Authorization", buildToken);
                return true;
            } else {
                response.setHeader("Authorization", authorization);
                return true;
            }

        }


    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {
        return super.onAccessDenied(request, response);
    }
}
